<template>
  <div class="groovy-editor-page">
    <!-- 顶部工具栏 -->
    <div class="editor-header">
      <div class="header-left">
        <a-button type="link" @click="handleBack">
          <template #icon>
            <Icon icon="ant-design:arrow-left-outlined" />
          </template>
          返回列表
        </a-button>
        
        <a-divider type="vertical" />
        
        <h3 class="editor-title">
          {{ scriptInfo?.id ? `编辑脚本: ${scriptInfo.displayName || scriptInfo.scriptName}` : '新建脚本' }}
        </h3>
      </div>

      <div class="header-right">
        <a-space>
          <a-button @click="handleSaveAs">
            <template #icon>
              <Icon icon="ant-design:copy-outlined" />
            </template>
            另存为
          </a-button>
          
          <a-button
            type="primary"
            :loading="saving"
            @click="handleSave"
          >
            <template #icon>
              <Icon icon="ant-design:save-outlined" />
            </template>
            保存
          </a-button>
        </a-space>
      </div>
    </div>

    <div class="editor-content">
      <!-- 左侧脚本信息 -->
      <div class="editor-sidebar">
        <a-card title="脚本信息" size="small">
          <InfoForm />
        </a-card>

        <!-- 快捷操作 -->
        <a-card title="快捷操作" size="small" class="mt-4">
          <a-space direction="vertical" style="width: 100%">
            <a-button
              block
              type="primary"
              ghost
              :loading="executing"
              @click="handleQuickTest"
            >
              <template #icon>
                <Icon icon="ant-design:play-circle-outlined" />
              </template>
              快速测试
            </a-button>

            <a-button block @click="showTemplates = true">
              <template #icon>
                <Icon icon="ant-design:snippets-outlined" />
              </template>
              代码模板
            </a-button>

            <a-button block @click="showHelp = true">
              <template #icon>
                <Icon icon="ant-design:question-circle-outlined" />
              </template>
              语法帮助
            </a-button>
          </a-space>
        </a-card>

        <!-- 版本信息 -->
        <a-card v-if="scriptInfo?.id" title="版本信息" size="small" class="mt-4">
          <a-descriptions :column="1" size="small">
            <a-descriptions-item label="当前版本">
              v{{ scriptInfo.version }}
            </a-descriptions-item>
            <a-descriptions-item label="创建时间">
              {{ dayjs(scriptInfo.createTime).format('YYYY-MM-DD HH:mm') }}
            </a-descriptions-item>
            <a-descriptions-item label="更新时间">
              {{ dayjs(scriptInfo.updateTime).format('YYYY-MM-DD HH:mm') }}
            </a-descriptions-item>
            <a-descriptions-item label="创建人">
              {{ scriptInfo.createBy }}
            </a-descriptions-item>
          </a-descriptions>
          
          <a-button block class="mt-2" @click="handleVersionHistory">
            查看版本历史
          </a-button>
        </a-card>
      </div>

      <!-- 右侧编辑器和测试区域 -->
      <div class="editor-main">
        <!-- 编辑器区域 -->
        <div class="editor-container">
          <GroovyEditor
            ref="editorRef"
            v-model:value="scriptContent"
            :script-info="scriptInfo"
            :height="showTestPanel ? `calc(100% - ${testPanelHeight + 50}px)` : '100%'"
            @save="handleSave"
            @execute="handleQuickTest"
          />
        </div>

        <!-- 底部测试面板 -->
        <div
          v-if="showTestPanel"
          class="test-panel"
          :style="{ height: testPanelHeight + 'px' }"
        >
          <div class="test-panel-header">
            <span>执行测试</span>
            <a-space>
              <a-button
                size="small"
                @click="testPanelHeight = testPanelHeight === 300 ? 200 : 300"
              >
                {{ testPanelHeight === 300 ? '收起' : '展开' }}
              </a-button>
              <a-button size="small" @click="showTestPanel = false">
                关闭
              </a-button>
            </a-space>
          </div>
          
          <div class="test-panel-content">
            <TestRunner
              :script-content="scriptContent"
              @execute="handleExecuteFromPanel"
            />
          </div>
        </div>
      </div>
    </div>

    <!-- 另存为弹窗 -->
    <AModal
      v-model:open="saveAsModalOpen"
      title="另存为新脚本"
      width="600px"
      @ok="handleSaveAsConfirm"
    >
      <SaveAsForm />
    </AModal>

    <!-- TestRunner模态框 -->
    <AModal
      v-model:open="showTestModal"
      title="Groovy脚本执行测试"
      width="800px"
      :footer="null"
      destroyOnClose
    >
      <TestRunner
        :data="testRunnerData"
        @success="onRefresh"
      />
    </AModal>
  </div>
</template>

<script setup lang="ts">
import type { VbenFormInstance } from '#/adapter/form';
import type { LowcodeGroovyApi } from '#/api/lowcode/groovy';

import { onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { Page, useVbenModal } from '@vben/common-ui';
import { Icon } from '@iconify/vue';
import dayjs from 'dayjs';

import { useVbenForm, z } from '#/adapter/form';
import { Modal as AModal, message } from 'ant-design-vue';
import {
  createGroovyScript,
  executeGroovyCode,
  getGroovyScript,
  updateGroovyScript,
} from '#/api/lowcode/groovy';
import GroovyEditor from '../modules/editor.vue';
import TestRunner from '../modules/test-runner.vue';

defineOptions({
  name: 'LowcodeGroovyEditor',
});

const route = useRoute();
const router = useRouter();

// const infoFormRef = ref<VbenFormInstance>(); // 已替换为 infoFormApi
// const saveAsFormRef = ref<VbenFormInstance>(); // 已替换为 saveAsFormApi
const editorRef = ref<InstanceType<typeof GroovyEditor>>();

const scriptInfo = ref<LowcodeGroovyApi.GroovyScript>();
const scriptContent = ref('');
const saving = ref(false);
const executing = ref(false);
const showTestPanel = ref(false);
const testPanelHeight = ref(300);
const saveAsModalOpen = ref(false);
const showTemplates = ref(false);
const showHelp = ref(false);

// TestRunner模态框控制
const showTestModal = ref(false);
const testRunnerData = ref<LowcodeGroovyApi.GroovyScript>();

// 信息表单配置
const infoFormSchema = [
  {
    fieldName: 'scriptName',
    label: '脚本标识',
    component: 'Input',
    componentProps: {
      placeholder: '请输入脚本唯一标识，如：test_script',
    },
    rules: z.string().min(1, '脚本标识不能为空').max(50, '脚本标识长度不能超过50个字符').regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, '脚本标识格式不正确，只能包含字母、数字和下划线，且以字母开头'),
  },
  {
    fieldName: 'displayName',
    label: '显示名称',
    component: 'Input',
    componentProps: {
      placeholder: '请输入脚本显示名称',
    },
    rules: z.string().min(1, '显示名称不能为空').max(100, '显示名称长度不能超过100个字符'),
  },
  {
    fieldName: 'category',
    label: '脚本分类',
    component: 'Select',
    componentProps: {
      placeholder: '请选择脚本分类',
      options: [
        { label: '数据处理', value: 'data' },
        { label: '业务逻辑', value: 'business' },
        { label: '工具函数', value: 'util' },
        { label: '定时任务', value: 'job' },
        { label: '接口集成', value: 'api' },
        { label: '其他', value: 'other' },
      ],
    },
    rules: z.string().nullable().optional(),
  },
  {
    fieldName: 'description',
    label: '脚本描述',
    component: 'Textarea',
    componentProps: {
      placeholder: '请输入脚本描述',
      rows: 3,
    },
    rules: z.string().max(500, '脚本描述长度不能超过500个字符').nullable().optional(),
  },
  {
    fieldName: 'status',
    label: '脚本状态',
    component: 'Select',
    componentProps: {
      placeholder: '请选择脚本状态',
      options: [
        { label: '启用', value: 1 },
        { label: '禁用', value: 0 },
      ],
    },
    rules: z.number().min(0).max(1, '脚本状态值无效'),
  },
  {
    fieldName: 'sort',
    label: '排序',
    component: 'InputNumber',
    componentProps: {
      placeholder: '请输入排序值',
      min: 0,
    },
    rules: z.number().min(0, '排序值不能为负数').nullable().optional(),
  },
];

// 创建表单实例
const [InfoForm, infoFormApi] = useVbenForm({
  schema: infoFormSchema,
  formOptions: {
    showActionButtonGroup: false,
    labelWidth: 80,
    colProps: { span: 24 },
    layout: 'horizontal'
  }
});

// 另存为表单配置
const saveAsFormSchema = [
  {
    fieldName: 'scriptName',
    label: '脚本标识',
    component: 'Input',
    componentProps: {
      placeholder: '请输入新脚本标识',
    },
    rules: z.string().min(1, '脚本标识不能为空').max(50, '脚本标识长度不能超过50个字符').regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, '脚本标识格式不正确'),
  },
  {
    fieldName: 'displayName',
    label: '显示名称',
    component: 'Input',
    componentProps: {
      placeholder: '请输入显示名称',
    },
    rules: z.string().min(1, '显示名称不能为空').max(100, '显示名称长度不能超过100个字符'),
  },
  {
    fieldName: 'category',
    label: '脚本分类',
    component: 'Select',
    componentProps: {
      placeholder: '请选择脚本分类',
      options: [
        { label: '数据处理', value: 'data' },
        { label: '业务逻辑', value: 'business' },
        { label: '工具函数', value: 'util' },
        { label: '定时任务', value: 'job' },
        { label: '接口集成', value: 'api' },
        { label: '其他', value: 'other' },
      ],
    },
    rules: z.string().nullable().optional(),
  },
  {
    fieldName: 'description',
    label: '脚本描述',
    component: 'Textarea',
    componentProps: {
      placeholder: '请输入脚本描述',
      rows: 3,
    },
    rules: z.string().max(500, '脚本描述长度不能超过500个字符').nullable().optional(),
  },
];

// 创建另存为表单实例
const [SaveAsForm, saveAsFormApi] = useVbenForm({
  schema: saveAsFormSchema,
  formOptions: {
    showActionButtonGroup: false,
    labelWidth: 80,
    colProps: { span: 24 },
    layout: 'horizontal'
  }
});

// 返回列表
const handleBack = () => {
  router.push({ name: 'LowcodeGroovyScript' });
};

// 刷新页面数据（TestModal成功回调）
const onRefresh = () => {
  if (scriptInfo.value?.id) {
    loadScript();
  }
};

// 加载脚本数据
const loadScript = async () => {
  const id = route.query.id as string;
  if (id) {
    try {
      const result = await getGroovyScript(Number(id));
      
      // 检查响应结构
      let data = result;
      if (result.data) {
        data = result.data;
      }
      
      scriptInfo.value = data;
      scriptContent.value = scriptInfo.value.scriptContent;
      
      // 设置表单数据
      const formValues = {
        scriptName: scriptInfo.value.scriptName,
        displayName: scriptInfo.value.displayName,
        category: scriptInfo.value.category,
        description: scriptInfo.value.description,
        status: scriptInfo.value.status,
        sort: scriptInfo.value.sort,
      };
      await infoFormApi.setValues(formValues);
    } catch (error: any) {
      console.error('加载脚本失败:', error);
      
      let errorMessage = '加载脚本失败';
      if (error?.response?.data?.message) {
        errorMessage = error.response.data.message;
      } else if (error?.message) {
        errorMessage = error.message;
      }
      
      message.error(errorMessage);
    }
  } else {
    // 新建脚本，设置默认内容
    scriptContent.value = `// Groovy脚本示例
// 可以在这里编写你的业务逻辑
// 
// 参数注释示例：
// @param userId int 用户ID
// @param userName string 用户名称
// @param isActive boolean 是否激活
// @param config object 配置信息

// 获取输入参数
def params = binding.params ?: [:]

// 获取具体参数
def userId = params.userId ?: 1
def userName = params.userName ?: "默认用户"
def isActive = params.isActive ?: true
def config = params.config ?: [timeout: 5000]

// 示例：处理业务逻辑
def processUserData = { id, name, active ->
    def result = [:]
    result.userId = id
    result.userName = name
    result.status = active ? "激活" : "禁用"
    result.processTime = new Date()
    return result
}

// 返回结果
return [
    success: true,
    message: "用户数据处理成功",
    data: processUserData(userId, userName, isActive),
    config: config
]`;
    
    // 设置默认表单数据
    await infoFormApi.setValues({
      category: 'business',
      status: 1,
      sort: 0,
    });
  }
};

// 保存脚本
const handleSave = async () => {
  try {
    const { valid } = await infoFormApi.validate();
    if (!valid) return;
    
    const infoValues = await infoFormApi.getValues();

    if (!scriptContent.value || !scriptContent.value.trim()) {
      message.error('脚本内容不能为空');
      return;
    }

    saving.value = true;

    // 确保数据格式符合后端期望
    const scriptData = {
      scriptName: infoValues.scriptName,
      displayName: infoValues.displayName,
      category: infoValues.category || null,
      description: infoValues.description || null,
      status: infoValues.status,
      scriptContent: scriptContent.value,
      sort: infoValues.sort || 0,
    };

    if (scriptInfo.value?.id) {
      // 更新现有脚本
      await updateGroovyScript({ ...scriptData, id: scriptInfo.value.id });
      message.success('脚本更新成功');
    } else {
      // 创建新脚本
      const result = await createGroovyScript(scriptData);
      
      // 检查响应结构
      let newScript = result;
      if (result.data) {
        newScript = result.data;
      }
      
      scriptInfo.value = newScript;
      message.success('脚本创建成功');
      
      // 更新URL，避免重复创建
      router.replace({
        name: 'LowcodeGroovyEditor',
        query: { id: newScript.id },
      });
    }

    // 重新加载脚本信息以获取最新版本号等
    if (scriptInfo.value?.id) {
      await loadScript();
    }
  } catch (error: any) {
    console.error('保存失败:', error);
    message.error(`保存失败: ${error?.message || '未知错误'}`);
  } finally {
    saving.value = false;
  }
};

// 另存为
const handleSaveAs = async () => {
  const infoValues = await infoFormApi.getValues();
  await saveAsFormApi.setValues({
    scriptName: infoValues?.scriptName ? `${infoValues.scriptName}_copy` : '',
    displayName: infoValues?.displayName ? `${infoValues.displayName}_副本` : '',
    category: infoValues?.category,
    description: infoValues?.description,
  });
  saveAsModalOpen.value = true;
};

// 确认另存为
const handleSaveAsConfirm = async () => {
  try {
    const { valid } = await saveAsFormApi.validate();
    if (!valid) return;
    
    const values = await saveAsFormApi.getValues();

    if (!scriptContent.value.trim()) {
      message.error('脚本内容不能为空');
      return;
    }

    saving.value = true;

    // 确保另存为数据格式符合后端期望
    const saveAsData = {
      scriptName: values.scriptName,
      displayName: values.displayName,
      category: values.category || null,
      description: values.description || null,
      status: 1, // 新脚本默认启用
      scriptContent: scriptContent.value,
      sort: 0,
    };
    const result = await createGroovyScript(saveAsData);
    
    // 检查响应结构
    let newScript = result;
    if (result.data) {
      newScript = result.data;
    }

    message.success('脚本另存为成功');
    saveAsModalOpen.value = false;

    // 跳转到新脚本的编辑页面
    router.replace({
      name: 'LowcodeGroovyEditor',
      query: { id: newScript.id },
    });

    await loadScript();
  } catch (error: any) {
    console.error('另存为失败:', error);
    message.error(`另存为失败: ${error?.message || '未知错误'}`);
  } finally {
    saving.value = false;
  }
};

// 快速测试 - 打开TestRunner模态框
const handleQuickTest = async () => {
  if (!scriptContent.value.trim()) {
    message.error('脚本内容不能为空');
    return;
  }

  // 获取当前表单数据
  const formValues = await infoFormApi.getValues();
  
  // 创建脚本数据对象传递给TestRunner，优先使用已保存的脚本信息，其次使用表单数据
  const scriptData = {
    scriptName: scriptInfo.value?.scriptName || formValues?.scriptName || '未命名脚本',
    displayName: scriptInfo.value?.displayName || formValues?.displayName || '未命名脚本',
    description: scriptInfo.value?.description || formValues?.description || '',
    scriptContent: scriptContent.value,
    status: scriptInfo.value?.status || formValues?.status || 1,
    id: scriptInfo.value?.id,
    category: scriptInfo.value?.category || formValues?.category,
  };

  testRunnerData.value = scriptData;
  showTestModal.value = true;
};

// 从测试面板执行
const handleExecuteFromPanel = () => {
  executing.value = false;
};

// 查看版本历史
const handleVersionHistory = () => {
  console.log('查看版本历史');
};

// 监听路由变化，重新加载数据
watch(
  () => route.query.id,
  () => {
    loadScript();
  }
);

onMounted(() => {
  loadScript();
});
</script>

<style scoped>
.groovy-editor-page {
  @apply flex flex-col;
  height: calc(100vh - 120px);
  position: relative;
  overflow: hidden;
}

.editor-header {
  @apply flex items-center justify-between px-4 py-2 bg-white border-b border-gray-200;
}

.header-left {
  @apply flex items-center;
}

.editor-title {
  @apply m-0 text-lg font-semibold;
}

.editor-content {
  @apply flex-1 flex;
  overflow: hidden;
}

.editor-sidebar {
  @apply w-80 bg-gray-50 border-r border-gray-200 p-4 overflow-y-auto;
}

.editor-main {
  @apply flex-1 flex flex-col;
  overflow: hidden;
}

.editor-container {
  @apply flex-1 p-4;
  overflow: hidden;
}

.test-panel {
  @apply border-t border-gray-200 bg-white;
  resize: vertical;
  overflow: auto;
  position: relative;
  z-index: 1;
}

.test-panel-header {
  @apply flex items-center justify-between px-4 py-2 bg-gray-50 border-b border-gray-200 font-medium;
}

.test-panel-content {
  @apply p-4 h-full overflow-auto;
}
</style>